package com.lms.netty.groupchat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.util.concurrent.GlobalEventExecutor;
import jdk.nashorn.internal.ir.CallNode;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author: 李孟帅
 * @CreateTime: 2020-06-17 14:02
 * @Description:
 */
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {
    /**
     * @Author 李孟帅
     * @Description 定义个channel组，管理所有的channel
     * GlobalEventExecutor.INSTANCE是全局的事件执行器，是一个单例
     * @Date 2020/6/17
     **/
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
    * @Author 李孟帅
    * @Description 连接一旦建立，就会执行，第一个被执行
    * @Date 2020/6/17
    **/
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //会将消息推送给群组里的其他客户端的channel。该方法会遍历所有的channel，并发送消息，不需要自己遍历
        channelGroup.writeAndFlush(sdf.format(new Date())+" [客户]-"+channel.remoteAddress()+"加入聊天");
        channelGroup.add(channel);
    }


    /**
    * @Author 李孟帅
    * @Description 表示channel处于活动状态，提示xx上线
    * @Date 2020/6/17 
    **/
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(sdf.format(new Date())+" "+ctx.channel().remoteAddress()+"上线了");
    }

    /**
    * @Author 李孟帅
    * @Description 表示channel处于不活动状态，提示下线
    * @Date 2020/6/17 
    **/
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(sdf.format(new Date())+" "+ctx.channel().remoteAddress()+"下线了");
    }

    /**
    * @Author 李孟帅
    * @Description 断开连接，将客户端离开信息推送给当前在线的客户
    * @Date 2020/6/17 
    **/
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.writeAndFlush(sdf.format(new Date())+" [客户]-"+channel.remoteAddress()+"离线了");
        System.out.println("channel group size:"+channelGroup.size());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("发生了异常："+cause.getMessage());
        ctx.close();
    }

    /**
    * @Author 李孟帅
    * @Description 读取数据，业务处理
    * @Date 2020/6/17
    **/
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.forEach(ch->{
            if (ch!=channel){
                ch.writeAndFlush(sdf.format(new Date())+"   [客户]-"+channel.remoteAddress()+"发送了消息"+msg);
            }else {
                ch.writeAndFlush(sdf.format(new Date())+"   [自己]-发送了消息"+msg);
            }
        });

    }
}
